from __future__ import absolute_import
import os
import tempfile
from subprocess import check_call, call
import logging
#import subprocess as sp

from forest.registry import register_tool
from forest.tool import Tool
from forest.tools.system.execute import poll
logger = logging.getLogger('forest.tools.system.mount')

@register_tool('system.mount')
def mount(device, mount_path, fs=None, loop=False):
    '''
    mounts in a subprocess.
    '''

    Tool.SIGNAL_TOOL_START(mount, level=logging.DEBUG, message='Mount: %s %s %s' % (device, fs, mount_path))

    if not os.path.exists(mount_path):
        os.makedirs(mount_path)

    if fs != 'swap':
        args = ['mount']

        if loop:
            args += ['-o', 'loop']

        if fs is not None:
            args += ['-t', fs]

        args += [device, mount_path]
        print args
        for line in poll(args):
            print line

@register_tool('system.bindmount')
def bindmount(path, mount_path):
    '''
    mounts in a subprocess.
    '''

    Tool.SIGNAL_TOOL_START(bindmount, level=logging.DEBUG, message='Bind Mount: %s %s' % (path, mount_path))

    args = ['mount', '--bind', path, mount_path]

    if not os.path.exists(mount_path):
        os.makedirs(mount_path)

    if not os.path.exists(mount_path):
        os.makedirs(mount_path)

    for line in poll(args):
        print line
    #pass



######## Execution contexts - use with the 'with' statement ##############

@register_tool('image.Mount')
class Mount(object):
    def __init__(self, dev, opts="", mnt=None):
        (self.dev, self.opts, self.mnt) = (dev, opts, mnt)

    def __enter__(self):
        self.mnt = _mount(self.dev, self.opts, self.mnt)
        return self.mnt

    def __exit__(self, exc_type, exc_value, traceback):
        umount(self.mnt)


def _mount(dev, opts="", mnt=None):
    '''Mount the given device at the given mountpoint, using the given opts.
    opts should be a comma-separated string of mount options.
    if mnt is none, a temporary directory will be created and its path will be
    returned.
    raises CalledProcessError if mount fails.'''
    if mnt is None:
        mnt = tempfile.mkdtemp(prefix="lorax.imgutils.")
    mount = ["mount"]
    if opts:
        mount += ["-o", opts]
    check_call(mount + [dev, mnt])
    return mnt

@register_tool('system.unmount')
def umount(mnt, force=True, loop=True, lazy=False):
    '''Unmount the given mountpoint. If the mount was a temporary dir created
    by mount, it will be deleted. Returns false if the unmount fails.'''

    args = ['umount']
    if force:
        args.append('-f')
    if loop:
        args.append('-d')

    if lazy:
        args.append('-l')
    args.append(mnt)

    rv = call(args)
    return (rv == 0)

